package com.zzf.concurrent.example.lock.custom;

import com.zzf.concurrent.example.lock.exception.TimeoutException;
import com.zzf.concurrent.example.util.TimeUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.stream.Stream;

/**
 * 使用wait & notify 实现自定义锁，可以控制锁的时间，以及何时释放锁
 * @author GaoFeng2017
 * @date 2019/8/7 8:49
 */
@Slf4j
public class CustomLockExample {

    public static void main(String[] args) {
        // lockTest();
        lockTimeoutTest();
    }

    private static void lockTest() {
        BooleanLock booleanLock = new BooleanLock();

        new Thread(() -> {
            booleanLock.lock();
            log.info("{} do something...");
            TimeUtil.sleep(2000);
            booleanLock.unlock();
            log.info("thread size is {}", booleanLock.getThreadSize());
        }, "T1").start();

        new Thread(() -> {
            booleanLock.lock();
            log.info("{} do something...");
            TimeUtil.sleep(2000);
            booleanLock.unlock();
            log.info("thread size is {}", booleanLock.getThreadSize());
        }, "T2").start();

    }

    private static void lockTimeoutTest() {
        BooleanLock lock = new BooleanLock();

        Stream.of("M1", "M2", "M3", "M4")
                .forEach(name -> {
                    new Thread(() -> {
                        Thread currentThread = Thread.currentThread();

                        try {
                            lock.lock(1000);
                        } catch (TimeoutException e) {
                           log.info("{} is timeout.", currentThread.getName());
                           return;
                        }

                        log.info("{} do something...", currentThread.getName());
                        TimeUtil.sleep(5000);
                        lock.unlock();
                    }, name).start();
                });


        lock.unlock();

    }
}
